<template>
  <div class="tree-node-single">
    <div
      class="tree-node-content"
      :class="{
        'is-selected': isSelected && isLeafNode,
        'is-leaf': isLeafNode,
        'is-selectable': isLeafNode,
      }"
      :style="indentStyle"
      @click="handleNodeClick"
    >
      <div
        class="expand-icon"
        @click.stop="$emit('toggle-expand', getNodeValue(node))"
      >
        <div
          v-if="hasChildren"
          class="arrow-right"
          :class="{ 'is-expanded': isExpanded }"
        ></div>
      </div>

      <!-- 只在叶子节点显示选择指示器 -->
      <div v-if="isLeafNode" class="node-indicator">
        <div v-if="isSelected" class="item-dot">
          <div class="item-dot-inner"></div>
        </div>
      </div>

      <span
        class="node-label"
        :class="{ 'is-selectable': isLeafNode }"
        @click.stop="handleLabelClick"
      >
        {{ getNodeLabel(node) }}
      </span>
    </div>

    <div v-if="hasChildren && isExpanded" class="tree-node-children">
      <TreeNodeSingle
        v-for="child in getNodeChildren(node)"
        :key="getNodeValue(child)"
        :node="child"
        :level="level + 1"
        :selected-value="selectedValue"
        :expanded-keys="expandedKeys"
        :field-names="fieldNames"
        @toggle-expand="$emit('toggle-expand', $event)"
        @select-node="$emit('select-node', $event)"
      />
    </div>
  </div>
</template>

<script>
export default {
  name: "TreeNodeSingle",
  props: {
    node: {
      type: Object,
      required: true,
    },
    level: {
      type: Number,
      default: 0,
    },
    selectedValue: {
      type: [String, Number],
      default: "",
    },
    expandedKeys: {
      type: Set,
      default: () => new Set(),
    },
    fieldNames: {
      type: Object,
      default: () => ({
        label: "label",
        value: "value",
        children: "children",
      }),
    },
  },
  emits: ["toggle-expand", "select-node"],
  computed: {
    isSelected () {
      return this.selectedValue === this.getNodeValue(this.node);
    },
    isExpanded () {
      return this.expandedKeys.has(this.getNodeValue(this.node));
    },
    hasChildren () {
      const nodeChildren = this.getNodeChildren(this.node);
      return nodeChildren && nodeChildren.length > 0;
    },
    isLeafNode () {
      return !this.hasChildren;
    },
    indentStyle () {
      return {
        paddingLeft: `${15 + this.level * 20}px`,
      };
    },
  },
  methods: {
    // 处理节点点击
    handleNodeClick () {
      // 只有叶子节点可以被选择
      if (this.isLeafNode) {
        this.$emit("select-node", this.node);
      } else {
        // 父节点点击时展开/收起
        this.$emit("toggle-expand", this.getNodeValue(this.node));
      }
    },

    // 处理标签点击
    handleLabelClick () {
      if (this.isLeafNode) {
        // 叶子节点：选择节点
        this.$emit("select-node", this.node);
      } else {
        // 父节点：展开/收起
        this.$emit("toggle-expand", this.getNodeValue(this.node));
      }
    },

    // 获取节点的指定字段值
    getNodeValue (node) {
      return node[this.fieldNames.value];
    },

    getNodeLabel (node) {
      return node[this.fieldNames.label];
    },

    getNodeChildren (node) {
      return node[this.fieldNames.children];
    },
  },
};
</script>

<style lang="less" scoped>
@primary-color: #4b58dc;
@transition-time: 0.3s;

.tree-node-single {
  .tree-node-content {
    display: flex;
    align-items: center;
    padding: 8px 15px 8px 0;
    cursor: pointer;
    transition: all @transition-time ease;
    position: relative;
    overflow: hidden;

    &:after {
      content: "";
      position: absolute;
      top: 0;
      left: -75%;
      width: 50%;
      height: 100%;
      background: linear-gradient(
        to right,
        rgba(255, 255, 255, 0),
        rgba(255, 255, 255, 0.4),
        rgba(255, 255, 255, 0)
      );
      transform: skewX(-15deg);
      transition: all 0.5s ease;
      opacity: 0;
    }

    &:hover {
      background-color: rgba(75, 88, 220, 0.05);

      &:after {
        left: 120%;
        opacity: 1;
      }

      .node-label {
        color: @primary-color;
      }
    }

    // 选中状态（只有叶子节点）
    &.is-selected {
      background: linear-gradient(
        to right,
        rgba(75, 88, 220, 0.08),
        rgba(75, 88, 220, 0.02)
      );
      border-left: 3px solid @primary-color;

      .node-label {
        color: @primary-color;
        font-weight: 500;
      }
    }

    // 非叶子节点样式
    &:not(.is-leaf) {
      cursor: pointer;

      .node-label {
        font-weight: 500;
        color: #2c3e50;
        cursor: pointer;
      }

      &:hover {
        .node-label {
          color: lighten(@primary-color, 10%);
        }
      }
    }

    // 可选择的叶子节点样式
    &.is-selectable {
      cursor: pointer;

      .node-label {
        cursor: pointer;
      }
    }

    .expand-icon {
      width: 20px;
      height: 20px;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-right: 5px;

      .arrow-right {
        width: 0;
        height: 0;
        border-top: 4px solid transparent;
        border-bottom: 4px solid transparent;
        border-left: 6px solid #c0c4cc;
        transition: transform @transition-time ease;

        &.is-expanded {
          transform: rotate(90deg);
        }
      }
    }

    .node-indicator {
      margin-right: 8px;

      .item-dot {
        width: 18px;
        height: 18px;
        border-radius: 50%;
        border: 1px solid @primary-color;
        display: flex;
        align-items: center;
        justify-content: center;
        background: #fff;

        .item-dot-inner {
          width: 10px;
          height: 10px;
          border-radius: 50%;
          background: linear-gradient(
            135deg,
            @primary-color,
            lighten(@primary-color, 20%)
          );
          animation: dot-scale 0.3s forwards;
        }
      }
    }

    .node-label {
      font-size: 14px;
      color: #606266;
      transition: color @transition-time ease;
      flex: 1;

      &.is-selectable {
        cursor: pointer;
      }
    }
  }

  .tree-node-children {
    border-left: 1px dashed #e4e7ed;
    margin-left: 25px;
  }
}

@keyframes dot-scale {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
  }
}
</style>
